﻿using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using Axelerate.Silverlight3D.Media.Media3D;
using System.Windows.Media;
using System.Windows.Input;

namespace EasySL.Controls
{
    public partial class TagCloud : UserControl
    {
        public TagCloud()
        {
            InitializeComponent();
        }

        public TagCloud(IList<Tag> tags)
        {
            this.InitializeComponent();
            this.m_tags = tags;
            this.m_slowDownCounter = 1000.0;
            this.Loaded += new RoutedEventHandler(TagCloud_Loaded);
        }

        void TagCloud_Loaded(object sender, RoutedEventArgs e)
        {
            if (!isLoaded)
                isLoaded = true;
            else
                return;

            this.FillTags();
            RotateTransform3D transformd = new RotateTransform3D();
            transformd.Rotation = new AxisAngleRotation3D(new Vector3D(1.0, 0.0, 0.0), 0.0);
            this.m_rotateTransform = transformd;
            CompositionTarget.Rendering += new EventHandler(CompositionTarget_Rendering);
            this.LayoutRoot.MouseEnter += new MouseEventHandler(LayoutRoot_MouseEnter);
            this.LayoutRoot.MouseLeave += new MouseEventHandler(LayoutRoot_MouseLeave);
            double x = 200.0;
            double num2 = 200.0;
            double num3 = Math.Sqrt(Math.Pow(x, 2.0) + Math.Pow(num2, 2.0)) / 170.0;
            this.m_rotateTransform.Rotation = new AxisAngleRotation3D(new Vector3D(num2, x, 0.0), num3);
        }

        void CompositionTarget_Rendering(object sender, EventArgs e)
        {
            if (!(this.m_runRotation || (this.m_slowDownCounter <= 0.0)))
            {
                AxisAngleRotation3D rotationd = (AxisAngleRotation3D)this.m_rotateTransform.Rotation;
                rotationd.Angle = rotationd.Angle * (this.m_slowDownCounter / 2500.0);
                this.m_rotateTransform.Rotation = rotationd;
                this.m_slowDownCounter--;
            }
            if (((AxisAngleRotation3D)this.m_rotateTransform.Rotation).Angle > 0.05)
            {
                this.RotateBlocks();
            }
        }

        void LayoutRoot_MouseLeave(object sender, MouseEventArgs e)
        {
            this.LayoutRoot.MouseMove -= new MouseEventHandler(LayoutRoot_MouseMove);
            this.m_runRotation = false;
        }

        void LayoutRoot_MouseEnter(object sender, MouseEventArgs e)
        {
            this.LayoutRoot.MouseMove += new MouseEventHandler(LayoutRoot_MouseMove);
            this.m_runRotation = true;
            this.m_slowDownCounter = 2500.0;
        }


        private void FillTags()
        {
            this.m_tagBlocks = new List<Tag3D>();
            double num = this.RootCanvas.Width / 3.0;
            int num2 = this.m_tags.Count;
            for (int i = 1; i < (num2 + 1); i++)
            {
                double a = Math.Acos(-1.0 + (((2.0 * i) - 1.0) / ((double)num2)));
                double d = Math.Sqrt(num2 * 3.1415926535897931) * a;
                double x = (num * Math.Cos(d)) * Math.Sin(a);
                double y = (num * Math.Sin(d)) * Math.Sin(a);
                double z = num * Math.Cos(a);
                Tag tag = this.m_tags[i - 1];
                Tag3D item = new Tag3D(x, y, z, tag.Name, tag.Link,  (ControlTemplate)this.Resources["CloudItem"]);
                item.Redraw(this.RootCanvas.Width / 2.0, this.RootCanvas.Height / 2.0);
                this.RootCanvas.Children.Add(item.LinkButton);
                this.m_tagBlocks.Add(item);
            }
        }


        void LayoutRoot_MouseMove(object sender, MouseEventArgs e)
        {
            Point position = e.GetPosition(this.RootCanvas);
            double x = position.X - (this.RootCanvas.ActualWidth / 2.0);
            x *= -1.8;
            double num2 = position.Y - (this.RootCanvas.ActualHeight / 2.0);
            num2 *= -1.8;
            double num3 = Math.Sqrt(Math.Pow(x, 2.0) + Math.Pow(num2, 2.0)) / 170.0;
            this.m_rotateTransform.Rotation = new AxisAngleRotation3D(new Vector3D(num2, x, 0.0), num3);
        }


        private void RotateBlocks()
        {
            foreach (Tag3D tagd in this.m_tagBlocks)
            {
                Point3D pointd;
                if (this.m_rotateTransform.TryTransform(tagd.CenterPoint, out pointd))
                {
                    tagd.CenterPoint = pointd;
                    tagd.Redraw(this.RootCanvas.ActualWidth / 2.0, this.RootCanvas.ActualHeight / 2.0);
                }
            }
        }

        private RotateTransform3D m_rotateTransform;
        private bool m_runRotation;
        private double m_slowDownCounter;
        private List<Tag3D> m_tagBlocks;
        private readonly IList<Tag> m_tags;
        private const double Slowdownvalue = 2500.0;
        private const double Speed = -1.8;
        private bool isLoaded;
    }
}
